package deviceCombo

import (
	"context"

	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/ent"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/ent/device"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/internal/svc"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/internal/utils/dberrorhandler"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/types/pancakebot"

	"github.com/suyuan32/simple-admin-common/utils/pointy"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetDeviceComboDetailLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetDeviceComboDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetDeviceComboDetailLogic {
	return &GetDeviceComboDetailLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetDeviceComboDetailLogic) GetDeviceComboDetail(in *pancakebot.DeviceComboListReq) (*pancakebot.DeviceComboDetailListResp, error) {
	// Query device by ID and eager load combos with their ingredients
	deviceEntity, err := l.svcCtx.DB.Device.Query().
		Where(device.ID(*in.DeviceId)).
		WithCombos(func(q *ent.ComboQuery) {
			q.WithComboIngredients(func(ciq *ent.ComboIngredientQuery) {
				ciq.WithIngredient() // Eager load ingredient details
			})
		}).
		Only(l.ctx)
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	// Convert device to DeviceInfo
	deviceInfo := &pancakebot.DeviceInfo{
		Id:           &deviceEntity.ID,
		CreatedAt:    pointy.GetPointer(deviceEntity.CreatedAt.UnixMilli()),
		UpdatedAt:    pointy.GetPointer(deviceEntity.UpdatedAt.UnixMilli()),
		DeviceName:   &deviceEntity.DeviceName,
		DeviceNo:     pointy.GetPointer(int64(deviceEntity.DeviceNo)),
		DeviceStatus: pointy.GetPointer(int64(deviceEntity.DeviceStatus)),
		Address:      &deviceEntity.Address,
		Ext:          &deviceEntity.Ext,
		Type:         pointy.GetPointer(int64(deviceEntity.Type)),
	}

	// Convert combos to ComboInfo list
	var combos []*pancakebot.ComboInfo
	if deviceEntity.Edges.Combos != nil {
		for _, c := range deviceEntity.Edges.Combos {
			comboInfo := &pancakebot.ComboInfo{
				Id:         &c.ID,
				CreatedAt:  pointy.GetPointer(c.CreatedAt.UnixMilli()),
				UpdatedAt:  pointy.GetPointer(c.UpdatedAt.UnixMilli()),
				Name:       &c.Name,
				Weight:     &c.Weight,
				Calories:   &c.Calories,
				Price:      &c.Price,
				ImgAddr:    &c.ImgAddr,
				TotalSales: pointy.GetPointer(int64(c.TotalSales)),
			}

			// Convert combo ingredients
			if c.Edges.ComboIngredients != nil {
				for _, ci := range c.Edges.ComboIngredients {
					comboIngredient := &pancakebot.ComboIngredientInfo{
						Id:           &ci.ID,
						CreatedAt:    pointy.GetPointer(ci.CreatedAt.UnixMilli()),
						UpdatedAt:    pointy.GetPointer(ci.UpdatedAt.UnixMilli()),
						ComboId:      &ci.ComboID,
						IngredientId: &ci.IngredientID,
						IsRequired:   &ci.IsRequired,
						Quantity:     pointy.GetPointer(int64(ci.Quantity)),
						Price:        &ci.Price,
					}

					// Convert ingredient details if available
					if ci.Edges.Ingredient != nil {
						ingredient := ci.Edges.Ingredient
						comboIngredient.Ingredient = &pancakebot.IngredientInfo{
							Id:        &ingredient.ID,
							CreatedAt: pointy.GetPointer(ingredient.CreatedAt.UnixMilli()),
							UpdatedAt: pointy.GetPointer(ingredient.UpdatedAt.UnixMilli()),
							Name:      &ingredient.Name,
							Unit:      &ingredient.Unit,
							Value:     pointy.GetPointer(int64(ingredient.Value)),
							ImageUrl:  &ingredient.ImageURL,
						}
					}

					comboInfo.Ingredients = append(comboInfo.Ingredients, comboIngredient)
				}
			}

			combos = append(combos, comboInfo)
		}
	}

	// Build response
	detailInfo := &pancakebot.DeviceComboDetailInfo{
		Device: deviceInfo,
		Combos: combos,
	}

	return &pancakebot.DeviceComboDetailListResp{
		Total: 1,
		Data:  []*pancakebot.DeviceComboDetailInfo{detailInfo},
	}, nil
}
